package utils;

import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import play.db.jpa.JPA;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.List;
import java.util.Map;

public class DBQuery {
    private String db = null;

    public DBQuery(String db) {
        this.db = db;
    }

    public DBQuery() {
    }

    /**
     * 创建查询对象
     *
     * @param sql
     * @param params
     * @return
     */
    private Query createQuery(String sql, Object... params) {
        EntityManager entityManager;
        if (db == null) {
            entityManager = JPA.em(JPA.DEFAULT);
        } else {
            entityManager = JPA.em(db);
        }
        Query query = entityManager.createNativeQuery(sql);
        if (params != null) {
            for (int i = 0; i < params.length; i++) {
                query.setParameter(i + 1, params[i]);
            }
        }
        query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        return query;
    }

    /**
     * 创建查询对象
     *
     * @param sql
     * @param param
     * @return
     */
    private Query createQuery(String sql, Map<String, Object> param) {
        EntityManager entityManager;
        if (db == null) {
            entityManager = JPA.em(JPA.DEFAULT);
        } else {
            entityManager = JPA.em(db);
        }
        Query query = entityManager.createNativeQuery(sql);
        if (param != null) {
            param.forEach(query::setParameter);
        }
        query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        return query;
    }

    public Map findToMap(String sql, Map<String, Object> param) {
        Object result = this.createQuery(sql, param).getSingleResult();
        if (result instanceof Map) {
            return (Map) result;
        }
        return null;
    }

    public Map findToMap(String sql, Object... params) {
        Object result = this.createQuery(sql, params).getSingleResult();
        if (result instanceof Map) {
            return (Map) result;
        }
        return null;
    }

    public List<Map> findToMapList(String sql, Object... params) {
        return (List<Map>) this.createQuery(sql, params).getResultList();
    }
}
